import { useModel } from 'umi';
import { amapKey, placeText } from '@/utils/amap';
import districtsInfo, { getDistrictCenter } from '@/utils/distrcts';
import { Role } from '@/utils/types.d';
import { PlusOutlined } from '@ant-design/icons';
import {
  ProCard,
  ProForm,
  ModalForm,
  ProFormSelect,
  ProFormText,
  ProFormUploadButton,
} from '@ant-design/pro-components';
import { Button, Input, Cascader, InputNumber, message, UploadFile, Modal } from 'antd';
import { useEffect, useState } from 'react';
import { Map as ReactMap, Marker } from 'react-amap';
import { createParkinglotNew, queryChargeRules, queryPatrolDevicsSN } from '../service';
import type { ParkinglotModalParam } from '../types';
import { queryCompanies } from '@/pages/SystemUser/service';
import { pklotReg } from '@/utils/utils';
import { RcFile } from 'antd/lib/upload';
import { getCompressionFileUrl } from '@/pages/Wechat/Complaint/utils';

let fileMap = new Map();
export default (props: { func: () => void }) => {
  const { initialState } = useModel('@@initialState');
  const userRole = initialState?.currentUser?.role;
  const [coordinate, setCoordinate] = useState<{ longitude: number; latitude: number }>({
    longitude: 120.37167,
    latitude: 30.305102,
  });
  useEffect(() => {
    fileMap = new Map();
    return () => {
      fileMap.clear();
    };
  }, []);
  const [form] = ProForm.useForm();
  const [fileList, setFileList] = useState<UploadFile[]>([]);
  const [previewOpen, setPreviewOpen] = useState(false);
  const [previewImage, setPreviewImage] = useState('');
  const [previewTitle, setPreviewTitle] = useState('');
  const [attributeMap, setAttributeMap] = useState<{ center: [number, number]; zoom: number }>({
    center: [120.37167, 30.305102],
    zoom: 4,
  });
  const filter = (inputValue: any, path: any) => {
    return path.some(
      (option: any) => option.name.toLowerCase().indexOf(inputValue.toLowerCase()) > -1,
    );
  };
  return (
    <ModalForm<ParkinglotModalParam>
      title="新建路段"
      width="85vw"
      form={form}
      modalProps={{
        destroyOnClose: true,
        maskClosable: false,
        onCancel: () => {
          fileMap.clear();
          setFileList(() => []);
        },
      }}
      layout="horizontal"
      labelCol={{ span: 6 }}
      wrapperCol={{ span: 16 }}
      trigger={
        <Button type="primary">
          <PlusOutlined /> 创建路段
        </Button>
      }
      onFinish={async (values) => {
        // const res = await createParkingLot({
        //   location: [values.coordinate.longitude, values.coordinate.latitude],
        //   ownerId: values.ownerId,
        //   parkingLotName: values.parkingLotName?.trim(),
        //   province: values.province,
        //   street: values.street?.trim(),
        //   address: values.address?.trim(),
        //   patrolDeviceId: values.patrolDeviceId,
        //   chargeRule: values.chargeRule,
        // });
        message.loading({ key: 'add_parkinglot', content: '正在处理，请稍后...' });
        const formParams = new FormData();
        fileList.forEach((item) => {
          formParams.append('imgs[]', item as RcFile);
        });
        formParams.append(
          'location',
          JSON.stringify([values.coordinate.longitude, values.coordinate.latitude]),
        );
        formParams.append('ownerId', values.ownerId || '');
        formParams.append('parkingLotName', values.parkingLotName?.trim() || '');
        formParams.append('province', JSON.stringify(values.province || []) || '');
        formParams.append('street', values.street?.trim() || '');
        formParams.append('address', values.address?.trim() || '');
        formParams.append('patrolDeviceId', JSON.stringify(values.patrolDeviceId || []));
        formParams.append('chargeRule', values.chargeRule || '');
        const res = await createParkinglotNew(formParams);
        if (res.success) {
          props.func();
          message.success({
            content: res.message,
            key: 'add_parkinglot',
          });
          form.resetFields();
          fileMap.clear();
          setFileList(() => []);
          return true;
        }
        message.error({
          content: res.message,
          key: 'add_parkinglot',
        });
        return false;
      }}
    >
      <div style={{ width: '100%', height: 720 }}>
        {/* @ts-ignore */}
        <ReactMap
          {...attributeMap}
          amapkey={amapKey}
          events={{
            click: (e: any) => {
              const longitude = e.lnglat.lng;
              const latitude = e.lnglat.lat;
              setCoordinate({ longitude, latitude });
              form.setFieldsValue({ coordinate: { longitude, latitude } });
            },
          }}
        >
          {coordinate && (
            // @ts-ignore
            <Marker
              title={`当前位置(${coordinate.longitude}, ${coordinate.latitude})`}
              position={[coordinate.longitude, coordinate.latitude]}
            />
          )}
          <Input.Search
            placeholder="输入关键字快速定位"
            style={{
              position: 'absolute',
              left: 10,
              top: 10,
              width: 200,
              marginLeft: 10,
            }}
            onSearch={(val, e) => {
              e?.stopPropagation();
              e?.preventDefault();
              placeText({ keywords: val }).then((body) => {
                if (!body || !body.pois[0]) return;
                const poi = body.pois[0].location.split(',').map((v: any) => Number(v));
                setAttributeMap({ center: [poi[0] + 0.005, poi[1]], zoom: 14 });
              });
            }}
          />
          <ProCard
            style={{
              position: 'absolute',
              right: 10,
              top: 10,
              bottom: 10,
              width: 600,
              marginLeft: 10,
              borderRadius: 15,
            }}
          >
            <ProFormText
              label="路段名称"
              name="parkingLotName"
              rules={[
                {
                  required: true,
                  validator: (_, val) => {
                    if (!val || pklotReg.test(val))
                      return Promise.reject(
                        new Error('路段名称不符合规范，特殊字符仅支持（）－ _ /'),
                      );
                    return Promise.resolve(val);
                  },
                },
              ]}
            />
            <ProForm.Item
              label="行政区域"
              name="province"
              rules={[{ type: 'array', required: true, message: '请选择路段位置' }]}
            >
              <Cascader
                // @ts-ignore
                getPopupContainer={(triggerNode) => triggerNode.parentElement}
                options={districtsInfo}
                fieldNames={{ label: 'name', value: 'name', children: 'districts' }}
                placeholder="请选择行政区域"
                onChange={(value: any) => {
                  if (value && value.length) {
                    const [Longitude, Latitude] = getDistrictCenter(value);
                    form.setFieldsValue({
                      coordinate: { longitude: Longitude, latitude: Latitude },
                    });
                    setAttributeMap({ center: [Longitude, Latitude], zoom: 12 });
                    setCoordinate({ longitude: Longitude, latitude: Latitude });
                  } else {
                    form.setFieldsValue({ coordinate: { longitude: 0, latitude: 0 } });
                  }
                }}
                showSearch={{ filter, matchInputWidth: false }}
              />
            </ProForm.Item>
            <ProForm.Item label="地理坐标">
              <Input.Group compact>
                <ProForm.Item name={['coordinate', 'longitude']} noStyle>
                  <InputNumber
                    style={{
                      width: '50%',
                      borderTopLeftRadius: '6px',
                      borderBottomLeftRadius: '6px',
                    }}
                    placeholder="点击地图拾取坐标"
                  />
                </ProForm.Item>
                <ProForm.Item name={['coordinate', 'latitude']} noStyle>
                  <InputNumber
                    style={{
                      width: '50%',
                      borderTopRightRadius: '6px',
                      borderBottomRightRadius: '6px',
                    }}
                    placeholder="点击地图拾取坐标"
                  />
                </ProForm.Item>
              </Input.Group>
            </ProForm.Item>
            <ProFormText
              label="街道名称"
              name="street"
              rules={[
                {
                  validator: (_, val) => {
                    if (val && pklotReg.test(val))
                      return Promise.reject(
                        new Error('街道名称不符合规范，特殊字符仅支持（）－ _ / ,'),
                      );
                    return Promise.resolve(val);
                  },
                },
              ]}
            />
            <ProFormText
              label="详细位置"
              name="address"
              rules={[
                {
                  validator: (_, val) => {
                    if (val && pklotReg.test(val))
                      return Promise.reject(
                        new Error('详细位置不符合规范，特殊字符仅支持（）－ _ / ,'),
                      );
                    return Promise.resolve(val);
                  },
                },
              ]}
            />
            <ProFormSelect
              name="patrolDeviceId"
              label="巡检设备"
              mode="multiple"
              debounceTime={300}
              showSearch
              placeholder="请选择巡检设备"
              rules={[
                {
                  validator: (_, val) => {
                    if (!val || val.length <= 3) {
                      return Promise.resolve(val);
                    }
                    return Promise.reject(new Error('一个路段最多关联3个巡检设备'));
                  },
                },
              ]}
              request={(val) => queryPatrolDevicsSN(val.keyWords)}
            />
            <ProFormSelect
              name="chargeRule"
              label="收费规则"
              debounceTime={300}
              showSearch
              placeholder="请选择收费规则，若无目标规则请前往收费规则模块进行创建"
              rules={[
                {
                  required: true,
                  message: '请选择收费规则，若无目标规则请前往收费规则模块进行创建',
                },
              ]}
              request={(val) => queryChargeRules(val.keyWords)}
            />
            {userRole === Role.ADMIN && (
              <ProFormSelect
                name="ownerId"
                label="路段所属公司"
                debounceTime={300}
                showSearch
                placeholder="请选择路段负责公司"
                request={(val) => queryCompanies(val.keyWords)}
              />
            )}
            <ProFormUploadButton
              label="路段图片"
              title="选择图片"
              tooltip="仅支持jpg, png, bmp为后缀的图片文件, 最大可上传4张"
              name="imgs"
              accept=".jpg,.png,.bmp"
              listType="picture-card"
              fileList={fileList?.map((item) => {
                return { ...item, thumbUrl: fileMap.get(item.uid) };
              })}
              fieldProps={{
                maxCount: 4,
                customRequest: () => {},
                beforeUpload: async (file: RcFile & { thumbUrl?: string }) => {
                  if (fileList.length >= 4) {
                    message.warn({
                      content: '已达上限, 如需继续上传, 请先删除部分图片',
                      key: 'add_parkinglot',
                    });
                    return false;
                  }
                  const isLt120K = file.size / 1024 < 300;
                  if (!isLt120K) {
                    message.warn({
                      content: '图片文件过大，请上传小于300k的图片',
                      key: 'add_parkinglot',
                    });
                    return false;
                  }
                  const thumbUrl = await getCompressionFileUrl(file);
                  fileMap.set(file.uid, thumbUrl);
                  setFileList([...fileList, file]);
                  return false;
                },
                onRemove: (file) => {
                  const index = fileList.indexOf(file);
                  const newFileList = fileList.slice();
                  newFileList.splice(index, 1);
                  fileMap.delete(file.uid);
                  setFileList(() => newFileList);
                },
                onPreview: (file) => {
                  setPreviewImage(fileMap.get(file.uid) || '');
                  setPreviewOpen(true);
                  setPreviewTitle(file.name);
                },
              }}
            />
          </ProCard>
          <Modal
            open={previewOpen}
            title={previewTitle}
            footer={null}
            onCancel={() => setPreviewOpen(false)}
            style={{ textAlign: 'center' }}
          >
            <img alt="example" style={{ width: '100%' }} src={previewImage} />
          </Modal>
        </ReactMap>
      </div>
    </ModalForm>
  );
};
